#include "UtilString.h"
#include "../Constantes.h"
#include <cstring>

using namespace std;


/**
 * Convierte un string a int.
 *
 * @params:
 * string* valor del string a convertir.
 * @return:
 * int con el valor de la cadena (0 si no pudo convertirlo)
 */
int UtilString::stringToInt(const string& valor){
	int retorno;
	istringstream stream(valor);
	return stream>>retorno? retorno:0;
}
bool UtilString::stringToBool(const string& valor){
	bool retorno;
	istringstream stream(valor);
	return stream>>retorno? retorno:false;
}

float UtilString::stringToFloat(const string& valor){
	float retorno;
	istringstream stream(valor);
	return stream>>retorno? retorno:0;
}

unsigned int UtilString::stringToUnsignedInt(const string& valor){
	unsigned int retorno;
	istringstream stream(valor);
	return stream>>retorno? retorno:0;
}


long int UtilString::stringToLongInt(const string& valor){
	long int retorno;
	istringstream stream(valor);
	return stream>>retorno? retorno:0;
}

int UtilString::charToInt(char valor[]){
	int retorno;
	istringstream stream(valor);
	return stream>>retorno? retorno:0;
}

long int UtilString::charToLongInt(char valor[]){
	long int retorno;
	istringstream stream(valor);
	return stream>>retorno? retorno:0;
}

/**
 * Convierte un int a un string.
 *
 * @params:
 * int valor del entero a convertir.
 * @return:
 * string con el valor del entero.
 */
string UtilString::intToString(const int& valor){
	string s;
	stringstream retorno;
	retorno << valor;
	return retorno.str();
}

string UtilString::floatToString(const float& valor){
	string s;
	stringstream retorno;
	retorno << valor;
	return retorno.str();
}

string UtilString::longUnsignedIntToString(const long unsigned int & valor){
	string s;
	stringstream retorno;
	retorno << valor;
	return retorno.str();
}

string UtilString::unsignedIntToString(const unsigned int& valor){
	string s;
	stringstream retorno;
	retorno << valor;
	return retorno.str();
}

string UtilString::TOlenghtStringStringValue(std::string& stream){
	string retorno;
	retorno = intToStringFixed(stream.size(),PLANO_MAX_LONG);
	retorno += stream;

	return retorno;
}

string UtilString::TOlenghtStringStringValue(int param){
	string stream = intToString(param);

	return TOlenghtStringStringValue(stream);
}

string UtilString::TOlenghtStringStringValue(float param){
	string stream = floatToString(param);

	return TOlenghtStringStringValue(stream);
}

string UtilString::TOlenghtStringStringValue(unsigned int param){
	string stream = unsignedIntToString(param);

	return TOlenghtStringStringValue(stream);
}
string UtilString::TOlenghtStringStringValue(long unsigned int param){
	string stream = longUnsignedIntToString(param);

	return TOlenghtStringStringValue(stream);
}


std::string UtilString::encontrarDelimitadores(const std::string &cadena, const std::string &primerDelimitador,
											   const std::string &segundoDelimitador)
{
	if ((!primerDelimitador.empty()) && (cadena.find(primerDelimitador) != std::string::npos))
	{
		return primerDelimitador;
	}

	if ((!segundoDelimitador.empty()) && (cadena.find(segundoDelimitador) != std::string::npos))
	{
		return segundoDelimitador;
	}

	return STRING_EMPTY;
}

string UtilString::FROMlenghtStringStringValue(std::string& stream){
	int tamOperacion =UtilString::stringToInt(stream.substr(0,PLANO_MAX_LONG));

	std::string operacionString = UtilString::obtenerToken(stream, tamOperacion);
	return operacionString;
}


string UtilString::intToStringFixed(const unsigned long& valor,unsigned long int maxSize){
	string s;
	stringstream retorno;
	retorno << valor;

	string strRetorno = retorno.str();

	unsigned long size = strRetorno.size();
	unsigned long caracteresBlancos= maxSize - size;
	string caracteresCeros;
	while(caracteresBlancos>0){
		caracteresCeros +="0";
		caracteresBlancos--;
	}

	caracteresCeros+=strRetorno;
	return caracteresCeros;
}

void UtilString::splitWithSeparator(vector<string>* retorno, const string& toSplit,const char& separator){
	string token;
	istringstream iss(toSplit);

	while ( getline(iss, token, separator) )
		retorno->push_back(token);

}


/**
 * Divide un string en un arreglo usando un char como separador
 *
 * @params:
 * @return:
 * Arreglo<string> con las cadenas separadas
 */
void UtilString::splitWithSeparator(vector<string>* retorno, string& toSplit){
	//Recorro haciendo los saltos que me dan los numeros de tamaño de bloque

	string token;
	while(!toSplit.empty()){
		token =FROMlenghtStringStringValue(toSplit);
		retorno->push_back(token);
		token.clear();
	}


}

std::string UtilString::obtenerToken(std::string &cadena, unsigned long tam){
	if (tam == 0) {
		cadena = cadena.substr(PLANO_MAX_LONG);
		return STRING_EMPTY;
	}

	std::string token = cadena.substr(PLANO_MAX_LONG, tam);

	if (!token.empty()){
		cadena = cadena.substr(token.size()+PLANO_MAX_LONG);
	}

	return token;
}


string UtilString::convertirEnString(vector<string>* aConvertir,string separador){
	string retorno;

	for(vector<string>::iterator it=aConvertir->begin() ; (it)!= aConvertir->end() ; ++it){
		retorno= *it + separador;
	}

	return retorno;
}

char* UtilString::copiarConstCharAChar(string origen){
	char* clave = new char[origen.size()+1];
	strcpy(clave,origen.c_str());
	return clave;
}

int UtilString::pxSize(std::string& stream){
	return stream.size() * DEFAULT_FONT_SIZE / 72 * DPI;
}
